home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / makeboot / makeBoot.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-05-13  |  3.8 KB  |  156 lines

  1. /*-
  2.  * makeBoot.c --
  3.  *    Program to take an executable and make it down-loadable by the
  4.  *    Sun PROM monitor boot code.
  5.  *
  6.  * Copyright (c) 1987 by the Regents of the University of California
  7.  *
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  *
  16.  *
  17.  */
  18. #ifndef lint
  19. static char rcsid[] =
  20. "$Header$ SPRITE (Berkeley)";
  21. #endif lint
  22.  
  23. #include    <sys/exec.h>
  24. #include    <sys/file.h>
  25. #include    <errno.h>
  26. extern int  errno;
  27. #include    <sys/types.h>
  28. #include    <sys/socket.h>
  29. #include    <netdb.h>
  30.  
  31. /*-
  32.  *-----------------------------------------------------------------------
  33.  * main --
  34.  *    The main function. Takes a program as the first argument and an
  35.  *    output file as the second argument. Strips and installs the program
  36.  *    in the output file in the boot directory with the header removed.
  37.  *    The program should be linked to start at 0x4000 (or where ever it
  38.  *    relocates itself to).
  39.  *
  40.  * Results:
  41.  *    None.
  42.  *
  43.  * Side Effects:
  44.  *    The output file is created.
  45.  *
  46.  *-----------------------------------------------------------------------
  47.  */
  48. main(argc, argv)
  49.     int              argc;
  50.     char      **argv;
  51. {
  52.     char      buffer[1024];
  53.     int              i;
  54.     int              in;
  55.     int              out;
  56.     char          *outName;
  57.     unsigned short *sp;
  58.     int              nb;
  59.     struct exec      header;
  60.     int              totalBytes;
  61.     extern char      *malloc();
  62.     struct hostent *he;
  63.  
  64.     if (argc < 3) {
  65.     printf("usage: %s <program> (<output> | -h <host>)\n", argv[0]);
  66.     exit(1);
  67.     }
  68.     
  69.     if (strcmp(argv[2], "-h") == 0) {
  70.     he = gethostbyname(argv[3]);
  71.     if (he == 0) {
  72.         printf("host %s unknown\n", argv[3]);
  73.         exit(1);
  74.     } else if (he->h_addrtype != AF_INET) {
  75.         printf("host not on internet\n");
  76.         exit(1);
  77.     } else {
  78.         char      *q;
  79.         char      addrBuf[sizeof("AABBCCDD")];
  80.         char      *x = "0123456789ABCDEF";
  81.         short     i;
  82.         char    *p;
  83.  
  84.         outName = malloc(sizeof("AABBCCDD") + strlen(BOOTDIR) + 1);
  85.  
  86.         q = he->h_addr;
  87.         sprintf(outName, "%s/", BOOTDIR);
  88.         p = outName + strlen(outName);
  89.         for(i = 4; i > 0; i--) {
  90.         *p++ = x[(*q >> 4) & 0xF];
  91.         *p++ = x[(*q++) & 0xF];
  92.         }
  93.         *p++ = '\0';
  94.     }
  95.     } else if (argv[2][0] == '/') {
  96.     outName = argv[2];
  97.     } else {
  98.     outName = malloc(strlen(argv[2]) + strlen(BOOTDIR) + 2);
  99.     sprintf(outName, "%s/%s", BOOTDIR, argv[2]);
  100.     }
  101.     
  102.     in = open(argv[1], O_RDONLY, 0);
  103.     if (in < 0) {
  104.     perror(argv[1]);
  105.     exit(1);
  106.     } else {
  107.     out = open(outName, O_CREAT|O_WRONLY|O_EXCL, 0666);
  108.     if ((out < 0) && (errno == EEXIST)) {
  109.         char  line[80];
  110.  
  111.         printf("%s exists, overwrite? ", outName);
  112.         gets(line);
  113.         if ((line[0] != 'Y') && (line[0] != 'y')) {
  114.         printf("aborted\n");
  115.         exit(1);
  116.         }
  117.         (void)unlink(outName);
  118.         out = open(outName, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  119.     }
  120.     fchmod(out, 0644);
  121.     }
  122.  
  123.     /*
  124.      * Strip off header and figure out how much data should really be there.
  125.      */
  126.     nb = read(in, &header, sizeof(header));
  127.     if (nb < 0) {
  128.     printf("Couldn't read header of %s\n", argv[1]);
  129.     exit(1);
  130.     }
  131.  
  132.     totalBytes = header.a_text + header.a_data;
  133.     
  134. #ifndef min
  135. #define min(a,b) (((a)<(b))?(a):(b))
  136. #endif /* min */
  137.  
  138.     do {
  139.     nb = read(in, buffer, min(sizeof(buffer),totalBytes));
  140.     totalBytes -= nb;
  141.     write(out, buffer, nb);
  142.     } while ((nb > 0) && (totalBytes > 0));
  143.  
  144.     if (totalBytes < 0) {
  145.     printf("Copied too much? (%d bytes)\n", -totalBytes);
  146.     } else if (totalBytes > 0) {
  147.     extern char *sys_errlist[];
  148.     
  149.     printf("Couldn't copy entire file: %s (%d bytes left)\n",
  150.            sys_errlist[errno],
  151.            totalBytes);
  152.     }
  153.     close(in);
  154.     close(out);
  155. }
  156.